Skip to content

Conversation

@Picazsoo
Copy link
Contributor

@Picazsoo Picazsoo commented Nov 18, 2025

Adds a new generator option useResponseEntity (default true) for kotlin-spring (identical option exists in java-spring). When disabled, controller methods return the model type directly instead of wrapping in ResponseEntity<>, and @ResponseStatus is added to preserve the HTTP status. (fixes #21833)

Also replaces the (very recently introduced by me) option declarativeInterfaceWrapResponses which is thus removed as the useResponseEntity can now control both and it does not make sense to keep both in place. However functionality depending on that option has not been yet released in any version other than SNAPSHOT.

Changes:

  • Introduced useResponseEntity config option. (default true)
  • Updated templates to conditionally wrap responses in ResponseEntity or add @ResponseStatus.
  • Adjusted imports to include org.springframework.http.ResponseEntity only when needed.
  • Preserves backward compatibility; default behavior remains unchanged.
  • remove "async" and "responseWrapper" from template as these are not supported by kotlin-spring generator - I presume this was ported over by accident when the kotlin-spring generator templates were bootstrapped by copied java-spring code.
  • put interface/controller method params on new lines to prevent super-long method signatures that make it complicated to reference the generated code in practice
  • fix incorrect double spaces in generated methods, fix spaces before commas. General cleanup

Motivation:
Provides flexibility for teams preferring direct model returns, aligning kotlin-spring with Java Spring generator capabilities and simplifying generated controller/interface signatures.

Breaking changes
This causes no breaking changes as the default behavior is unchanged. The only minor breaking change is the removal of declarativeInterfaceWrapResponses option. The behavior controlled by this option is now also tied to the new useResponseEntity option.

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request. - Tagging @karismann, @Zomzog, @andrewemery, @4brunu, @yutaka0m, @stefankoppier, @e5l

@Picazsoo Picazsoo changed the title remove "async" and "responseWrapper" from template as these are not s… [kotlin-spring][server] Feat: Return from controllers without ResponseEntity wrapper. Nov 18, 2025
@Picazsoo Picazsoo force-pushed the feature/21833-Option-to-disable-ResponseEntity-wrapping-in-kotlin-spring-generator branch from 10c3d76 to 2f80415 Compare November 18, 2025 16:40
)
fun addPet( @Valid @RequestBody pet: Pet): ResponseEntity<Pet> {
fun addPet(
@Valid @RequestBody pet: Pet
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am aware that this is not optimal (one would prefer to have this single param on one line with the opening and closing parentheses), but I think the trade-off is worth it for the multi-param methods

Comment on lines 115 to 119
fun updatePetWithForm(
@PathVariable("petId") petId: kotlin.Long,
@Valid @RequestParam(value = "name", required = false) name: kotlin.String? ,
@Valid @RequestParam(value = "status", required = false) status: kotlin.String?
): ResponseEntity<Unit> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is definitely an improvement over the current state of things. These signatures can get really long with all the annotations and then referencing the interface or controllers becomes quite cumbersome with a lot of horizontal scrolling.

Comment on lines +139 to +147
//for your own safety never directly reuse these path definitions in tests
const val PATH_ADD_PET: String = "/pet"
const val PATH_DELETE_PET: String = "/pet/{petId}"
const val PATH_FIND_PETS_BY_STATUS: String = "/pet/findByStatus"
const val PATH_FIND_PETS_BY_TAGS: String = "/pet/findByTags"
const val PATH_GET_PET_BY_ID: String = "/pet/{petId}"
const val PATH_UPDATE_PET: String = "/pet"
const val PATH_UPDATE_PET_WITH_FORM: String = "/pet/{petId}"
const val PATH_UPLOAD_FILE: String = "/pet/{petId}/uploadImage"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea behind this is that controller paths are generated as simple const val inside a companion object. Then in tests, the same paths can be manually redefined in a centralized utility class (often combined with a base path) to maintain explicit control and allow efficient DRY use across controller and integration tests. A unit test then asserts that each test path equals the corresponding generated path (or basePath + generatedPath), ensuring any divergence between controller and test definitions is caught while still allowing safe refactoring.

So that's why I would like to expose the paths like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REQ][kotlin-spring] Option to disable ResponseEntity wrapping in kotlin-spring generator

1 participant